home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 25 / CU Amiga Magazine's Super CD-ROM 25 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-08].iso / CUCD / Programming / QuakeTools / src / libqbuild / outside.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-06-11  |  5.2 KB  |  255 lines

  1. #define    LIBQBUILD_CORE
  2. #include "../include/libqbuild.h"
  3.  
  4. int outleafs = 0;                // 4
  5.  
  6. struct portal *prevleaknode;            // 4
  7. FILE *leakfile;                    // 4
  8.  
  9. int hit_occupied = 0;                // 4
  10. int backdraw = 0;                // 4
  11. /* PROGRESS-ONLY! */
  12. int outsidenum;
  13. int outsidecur;
  14.  
  15. /*
  16.  * ===========
  17.  * PointInLeaf
  18.  * ===========
  19.  */
  20. struct node *PointInLeaf(__memBase, struct node * node, vec3_t point)
  21. {
  22.   vec_t d;
  23.  
  24.   if (node->contents)
  25.     return node;
  26.  
  27. #ifdef EXHAUSIVE_CHECK
  28.   if(node->planenum >= bspMem->numbrushplanes || node->planennum < 0)
  29.     Error("looking for nonexisting plane %d\n", node->planenum);
  30. #endif
  31.   d = DotProduct(bspMem->brushplanes[node->planenum].normal, point) - bspMem->brushplanes[node->planenum].dist;
  32.  
  33.   if (d > 0)
  34.     return PointInLeaf(bspMem, node->children[0], point);
  35.  
  36.   return PointInLeaf(bspMem, node->children[1], point);
  37. }
  38.  
  39. /*
  40.  * ===========
  41.  * PlaceOccupant
  42.  * ===========
  43.  */
  44. bool PlaceOccupant(__memBase, register int num, register vec3_t point, register struct node * headnode)
  45. {
  46.   struct node *n;
  47.  
  48.   n = PointInLeaf(bspMem, headnode, point);
  49.   if (n->contents == CONTENTS_SOLID)
  50.     return FALSE;
  51.   n->occupied = num;
  52.   return TRUE;
  53. }
  54.  
  55. /*
  56.  * ==============
  57.  * MarkLeakTrail
  58.  * ==============
  59.  */
  60. void MarkLeakTrail(register struct portal * n2)
  61. {
  62.   int i;
  63.   short int j;
  64.   vec3_t p1, p2, dir;
  65.   float len;
  66.   struct portal *n1;
  67.  
  68.   if (hullnum)
  69.     return;
  70.  
  71.   n1 = prevleaknode;
  72.   prevleaknode = n2;
  73.  
  74.   if (!n1)
  75.     return;
  76.  
  77.   VectorCopy(n2->winding->points[0], p1);
  78.   for (i = 1; i < n2->winding->numpoints; i++) {
  79.     for (j = 0; j < 3; j++)
  80.       p1[j] = (p1[j] + n2->winding->points[i][j]) / 2;
  81.   }
  82.  
  83.   VectorCopy(n1->winding->points[0], p2);
  84.   for (i = 1; i < n1->winding->numpoints; i++) {
  85.     for (j = 0; j < 3; j++)
  86.       p2[j] = (p2[j] + n1->winding->points[i][j]) / 2;
  87.   }
  88.  
  89.   VectorSubtract(p2, p1, dir);
  90.   len = VectorLength(dir);
  91.   VectorNormalize(dir);
  92.  
  93.   while (len > 2) {
  94.     fprintf(leakfile, "%g %g %g\n", p1[0], p1[1], p1[2]);
  95.     for (i = 0; i < 3; i++)
  96.       p1[i] += dir[i] * 2;
  97.     len -= 2;
  98.   }
  99. }
  100.  
  101. /*
  102.  * ==================
  103.  * RecursiveFillOutside
  104.  * 
  105.  * If fill is FALSE, just check, don't fill
  106.  * Returns TRUE if an occupied leaf is reached
  107.  * ==================
  108.  */
  109. bool RecursiveFillOutside(register struct node * l, register bool fill)
  110. {
  111.   struct portal *p;
  112.   int s;
  113.   
  114.   /* PROGRESS-ONLY! */
  115.   if(fill == FALSE)
  116.     outsidenum++;
  117.   else
  118.     mprogress(outsidenum, ++outsidecur);
  119.  
  120.   if (l->contents == CONTENTS_SOLID || l->contents == CONTENTS_SKY)
  121.     return FALSE;
  122.  
  123.   if (l->valid == valid)
  124.     return FALSE;
  125.  
  126.   if (l->occupied)
  127.     return TRUE;
  128.  
  129.   l->valid = valid;
  130.  
  131. // fill it and it's neighbors
  132.   if (fill)
  133.     l->contents = CONTENTS_SOLID;
  134.   outleafs++;
  135.  
  136.   for (p = l->portals; p;) {
  137.     s = (p->nodes[0] == l);
  138.  
  139.     if (RecursiveFillOutside(p->nodes[s], fill)) {                   // leaked, so stop filling
  140.  
  141.       if (backdraw-- > 0) {
  142.     MarkLeakTrail(p);
  143.     DrawLeaf(l, 2);
  144.       }
  145.       return TRUE;
  146.     }
  147.     p = p->next[!s];
  148.   }
  149.  
  150.   return FALSE;
  151. }
  152.  
  153. /*
  154.  * ==================
  155.  * ClearOutFaces
  156.  * 
  157.  * ==================
  158.  */
  159. void ClearOutFaces(register struct node * node)
  160. {
  161.   struct visfacet **fp;
  162.  
  163.   if (node->planenum != -1) {
  164.     ClearOutFaces(node->children[0]);
  165.     ClearOutFaces(node->children[1]);
  166.     return;
  167.   }
  168.   if (node->contents != CONTENTS_SOLID)
  169.     return;
  170.  
  171.   for (fp = node->markfaces; *fp; fp++) {
  172.     // mark all the original faces that are removed
  173.     (*fp)->numpoints = 0;
  174.   }
  175.   node->faces = NULL;
  176. }
  177.  
  178. //=============================================================================
  179.  
  180. /*
  181.  * ===========
  182.  * FillOutside
  183.  * 
  184.  * ===========
  185.  */
  186. bool FillOutside(__memBase, struct node * node, char *pointfilename)
  187. {
  188.   int s;
  189.   vec_t *v;
  190.   int i;
  191.   bool inside;
  192.  
  193.   mprintf("----- FillOutside -------\n");
  194.   /* PROGRESS-ONLY! */
  195.   outsidenum = 0;
  196.   outsidecur = 0;
  197.  
  198.   if (bspMem->bspOptions & QBSP_NOFILL) {
  199.     mprintf("    - skipped\n");
  200.     return FALSE;
  201.   }
  202.  
  203.   inside = FALSE;
  204.   for (i = 1; i < bspMem->nummapentities; i++) {
  205.     if (!VectorZero(bspMem->mapentities[i].origin)) {
  206.       if (PlaceOccupant(bspMem, i, bspMem->mapentities[i].origin, node))
  207.     inside = TRUE;
  208.     }
  209.   }
  210.  
  211.   if (!inside) {
  212.     mprintf("Hullnum %i: No bspMem->mapentities in empty space -- no filling performed\n", hullnum);
  213.     return FALSE;
  214.   }
  215.  
  216.   s = !(outside_node.portals->nodes[1] == &outside_node);
  217.  
  218. // first check to see if an occupied leaf is hit
  219.   outleafs = 0;
  220.   valid++;
  221.  
  222.   prevleaknode = NULL;
  223.  
  224.   if (!hullnum) {
  225.     leakfile = fopen(pointfilename, "w");
  226.     if (!leakfile)
  227.       Error("Couldn't open %s\n", pointfilename);
  228.   }
  229.  
  230.   if (RecursiveFillOutside(outside_node.portals->nodes[s], FALSE)) {
  231.     v = bspMem->mapentities[hit_occupied].origin;
  232.     eprintf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
  233.     eprintf("reached occupant at: ( %g %g %g )\n"
  234.         ,v[0], v[1], v[2]);
  235.     eprintf("no filling performed\n");
  236.     if (!hullnum)
  237.       fclose(leakfile);
  238.     eprintf("leak file written to %s\n", pointfilename);
  239.     eprintf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
  240.     return FALSE;
  241.   }
  242.   if (!hullnum)
  243.     fclose(leakfile);
  244.  
  245. // now go back and fill things in
  246.   valid++;
  247.   RecursiveFillOutside(outside_node.portals->nodes[s], TRUE);
  248.  
  249. // remove faces from filled in leafs    
  250.   ClearOutFaces(node);
  251.  
  252.   mprintf("%5i outleafs\n", outleafs);
  253.   return TRUE;
  254. }
  255.